/* Author: David McCoy dave.mccoy@cospandesign.com
 *
 *     This file is part of DLCM\SubServ.
 *
 *  DLCM\SubServ is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  DLCM\SubServ is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with DLCM\SubServ.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 * Main.java
 *
 * Main entry point for DLCM SubServ
 *
 * Created on Mar 21, 2010, 1:40:00 AM
 */

package com.cospandesign.gui;

import com.cospandesign.gui.lcm.SubServTCPService;
import com.cospandesign.gui.lcm.SubServTCPServiceNotify;
import com.cospandesign.gui.providers.ProviderGeneratorInterface;
import com.cospandesign.gui.providers.ProviderGuiGenerator;
import com.cospandesign.gui.pubsub.PubSubProvider;
import dlcm.StructureListener;
import dlcm.StructureManager;
import java.awt.Color;
import java.awt.Component;
import java.awt.Toolkit;
import java.io.IOException;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingWorker;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;


/**
 *
 * @author cospan
 */
public class Main extends javax.swing.JFrame implements StructureListener, SubServTCPServiceNotify{

    private static String PUBSUB_STRING = "PubSub";
    HashMap<String, PubSubProvider> PubSubMap;
    HashMap<String, ProviderGuiGenerator> ProviderMap;
    //HashMap<String, String> ProviderVariableMap;
    StructureManager mStructureManager;

    private String ProviderName;
    private String ProviderType;

    SubServTCPService TCPServerLCM;
    Integer ServerPort;
    int nNumOfClients = 0;
    static final int SERVER_PORT_NUMBER = 7600;

    int StatusLevel = 0;

    /** Creates new form SubServ */
    public Main() {

        initComponents();

        RedirectConsole();
        //Setup the properties
        
        ServerPort = new Integer (SERVER_PORT_NUMBER);
        mStructureManager = new StructureManager();
        Integer RandomNumber = (new Random()).nextInt(1000);
        ProviderNameTextField.setText(PUBSUB_STRING + RandomNumber.toString());

        ArrayList<String> providerNames = new ArrayList<String>();
        this.providerTypeList.removeAll();

        for (Component c : this.ProviderLayeredPanel.getComponents()){
            providerNames.add(c.getName());
            ProviderLayeredPanel.moveToBack(c);
        }


        Object[] providerNamesStrings = new String[providerNames.size()];
        providerNamesStrings = providerNames.toArray();
        providerTypeList.setListData(providerNamesStrings);


        PubSubMap = new HashMap<String, PubSubProvider>();
        //bindingGroup.addBindingListener(new LoggingBindingListener());
        //mStructureManager = mainApp.getStructureManager();
        structureViewer.setStructureManager(mStructureManager);
        lcmGen.SetStructureManager(mStructureManager);
        mStructureManager.addStructureListener(this);

        this.providerTypeList.addListSelectionListener(new ListSelectionListener() {

            public void valueChanged(ListSelectionEvent e) {
                ProviderListChangeListener();
                //mainApp.setProviderType(PUBSUB_STRING);
            }
        });

 

        if (providerNamesStrings.length > 0){
            providerTypeList.setSelectedIndex(0);
        }
        if (providerNames.contains("TCP")){
            providerTypeList.setSelectedValue("TCP", true);
        }
         
        MainDebug("Main Initialized");
    }

    public void structureChanging(){


    }
    public void structureChanged(){
        MainInfo("StructueMap has changed");
        for (String name : PubSubMap.keySet()){
            PubSubMap.get(name).MainStructureMapChanged();
        }
        structureViewer.updateStructureManager();
        
    }

    //  <editor-fold defaultstate="collapsed" desc="Provder Functions">
    public String getSelectedProvider(){
        if (!(providerTypeList.getSelectedValue().getClass().equals(String.class))) {
        
            return "TCP";
        }
        return (String)providerTypeList.getSelectedValue();
    }
    public void ProviderListChangeListener(){
        Component component = null;
        Component[] components = ProviderLayeredPanel.getComponents();
        for (Component c : components){
            if (c.getName().equals((String)providerTypeList.getSelectedValue())){
                component = c;
            }
            else {
                c.setVisible(false);
            }
        }
        component.setVisible(true);
        ProviderLayeredPanel.moveToFront(component);
    }
    public String getPubSubName(){
        Integer RandomNumber = (new Random()).nextInt(1000);
        if (ProviderNameTextField.getText() == null){
            ProviderNameTextField.setText(PUBSUB_STRING + RandomNumber.toString());
        }
        return this.ProviderNameTextField.getText();
    }
    //  </editor-fold>

    //  <editor-fold defaultstate="collapsed" desc="Structure Manager">
    public void ParseStructureString (String ParseString) throws Exception{
    mStructureManager.parseString(ParseString);/*
    mStructureManager.parseString(	"struct buttons_t \n" +
					"{\n" +
					"       int8_t address;\n" +
					"       int32_t value;\n" +
					"}\n" +
					"\n" +
					"struct leds_t\n" +
					"{\n" +
					"       int16_t width;\n" +
					"	   int8_t address;\n" +
					"       int8_t intensity;\n" +
					"}\n" +
					"\n" +
					"struct adc_t\n" +
					"{\n" +
					"       int16_t width;\n" +
					"	   int16_t address;\n" +
					"       int32_t value;\n" +
					"}\n" +
					"\n" +
					"struct dac_t\n" +
					"{\n" +
					"       int16_t width;\n" +
					"	   int16_t address;\n" +
					"       int32_t value; \n" +
					"}"		);

*/
    }
    //  </editor-fold>

    //  <editor-fold defaultstate="collapsed" desc="TCP Server">
    public boolean StartServer() throws IOException{
        try {
            Integer port = Integer.parseInt(this.PortTextBox.getText());

        }
        catch (Exception ex){
            PortTextBox.setBackground(Color.red);
            MainError(ex.getMessage());
            return false;
        }
        TCPServerLCM = new SubServTCPService(ServerPort, this);
        return true;
    }
    public Integer getServerPort(){
        return ServerPort;
    }
    public void setServerPort(Integer serverPort){
        ServerPort = serverPort;
    }
//  </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="PubSub functions">
    public void ChildNotifyParentClosing(String childName){
        PubSubProvider child = PubSubMap.get(childName);
        PubSubMap.remove(childName);
        
    }
    private String generateURL(){

        String url = new String ("");
        HashMap<String, String> providerVariableMap = null;// = new HashMap<String, String>();
        Component component = null;
        Component[] components = ProviderLayeredPanel.getComponents();
        for (Component c : components){
            if (c.getName().equals((String)providerTypeList.getSelectedValue())){
                component = c;
            }
        }

        ProviderGeneratorInterface pgi = (ProviderGeneratorInterface) component;
        String ProviderName = pgi.getProviderName();
        providerVariableMap = pgi.getProviderVariables();

        url += providerVariableMap.get("protocol");
        url += "://";
        url += providerVariableMap.get("network");

        if (providerVariableMap.size() > 2){
            for (String key : providerVariableMap.keySet()){
                if (key.equals("protocol")){
                    continue;
                }
                if (key.equals("network")){
                    continue;
                }
                url += "?" + key + "=" + providerVariableMap.get(key);
            }
        }
        return url;
    }
    private Color GenerateColor (){

        Integer r = (new Random()).nextInt(255 - 160);
        r += 160;
        Integer g = (new Random()).nextInt(255 - 160);
        g += 160;
        Integer b = (new Random()).nextInt(255 - 160);
        b += 160;
        Integer rgb = (r << 16) + (g << 8) + (b);
        Color color = Color.getColor(null, rgb);
        return color;
    }
    private void createPubSub(){
        PubSubProvider provider = null;
        if (((String)providerTypeList.getSelectedValue()).equals("TCP")){
            if (TCPServerLCM == null){
                try {
                    StartServer();
                } catch (IOException ex) {
                    MainError("Starting Server: " + ex.getMessage());
                }
            }
        }
        try {
            provider = new PubSubProvider(this, getPubSubName(), generateURL(), mStructureManager, GenerateColor());
        }
        catch (Exception ex){
            this.MainError(ex.getMessage());
        }
        PubSubMap.put(getPubSubName(), provider);
        provider.setProviderString(generateURL());
        provider.setVisible(true);
        Integer RandomNumber = (new Random()).nextInt(1000);
        RandomNumber = (new Random()).nextInt(1000);
        ProviderNameTextField.setText(PUBSUB_STRING + RandomNumber.toString());
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Status Functions">
    public void FilterLevelChanged (String level){
        StatusMessageBox.append("Status Level changed to " + level + "\n");
    }
    public void MainFatal (String fatal){
        if (StatusLevel <= 5){
            StatusMessageBox.append("Fatal: " + fatal + "\n");
        }
    }
    public void MainError (String error){
        if (StatusLevel <= 4){
            StatusMessageBox.append("Error: " + error + "\n");
        }
    }
    public void MainWarning (String warning){
        if (StatusLevel <= 3){
            StatusMessageBox.append("Warning: " + warning + "\n");
        }
    }
    public void MainImportant (String important){
        if (StatusLevel <= 2){
            StatusMessageBox.append("Important: " + important + "\n");
        }
    }
    public void MainInfo (String info){
        if (StatusLevel <= 1){
            StatusMessageBox.append("Info: " + info + "\n");
        }
    }
    public void MainDebug (String debug){
        StatusMessageBox.append("Debug: " + debug + "\n");
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Server">
    public void clientConnecting(int numOfClients) {
        nNumOfClients = numOfClients;
        System.out.println("Client Connected!");
        System.out.println("Number of Cleints = " + (new Integer(numOfClients )).toString());
    }

    public void clientDisconnecting(int numOfClients) {
        nNumOfClients = numOfClients;
        System.out.println("Client Disconnected!");
        System.out.println("Number of Cleints = " + (new Integer(numOfClients )).toString());
    }

    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Redirect Console">
    private final PipedInputStream VirtualOutputStream = new PipedInputStream();
    private final PipedInputStream VirtualOutputErrorStream = new PipedInputStream();

    private StdOutSwingWorking StdOutReader;
    private StdErrSwingWorker StdErrReader;

    private void RedirectConsole(){

        //Setup stdout
        try {
            PipedOutputStream StandardOutputStream = new PipedOutputStream(VirtualOutputStream);
            System.setOut(new PrintStream(StandardOutputStream, true));
        } catch (IOException ex) {
            MainFatal(ex.getMessage());
        }
        try {
            PipedOutputStream StandardOutErrorStream = new PipedOutputStream(VirtualOutputErrorStream);
            System.setErr(new PrintStream(StandardOutErrorStream, true));
        } catch (IOException ex) {
            MainFatal(ex.getMessage());
        }
        StdOutReader = new StdOutSwingWorking();
        StdErrReader = new StdErrSwingWorker();
        try {
            StdOutReader.execute();
            StdErrReader.execute();
        } catch (Exception ex) {
            MainFatal(ex.getMessage());
        }

    }

    private class StdOutSwingWorking extends SwingWorker<String, String>   {

        @Override
        protected String doInBackground() throws Exception {
            int firstCharacter = 0;
            while (true && !this.isCancelled()){
                //Thread.sleep(100);
                //System.out.wait(100);
                String input = "";
                firstCharacter = VirtualOutputStream.read();
                if (VirtualOutputStream.available() > 0){
                    byte b[] = new byte[VirtualOutputStream.available() + 1];
                    b[0] = (byte) firstCharacter;
                    VirtualOutputStream.read(b, 1, b.length - 1);
                    input = new String(b);
                    this.publish(input);
                }
            }
            return "done";
        }

        @Override
        protected void process(List<String> chunks) {
            for (String string : chunks){
                if (StatusLevel == 0){
                    StatusMessageBox.append(string);
                }
            }
            super.process(chunks);
        }
    }
    private class StdErrSwingWorker extends SwingWorker<String, String> {

        @Override
        protected String doInBackground() throws Exception {
            int firstCharacter = 0;
            while (true && !this.isCancelled()){
                Thread.sleep(100);
                String input = "";
                firstCharacter = VirtualOutputErrorStream.read();
                if (VirtualOutputErrorStream.available() > 0){
                    byte b[] = new byte[VirtualOutputErrorStream.available() + 1];
                    b[0] = (byte) firstCharacter;
                    VirtualOutputErrorStream.read(b, 1, b.length - 1);
                    input = new String(b);
                    this.publish(input);
                }
            }
            return "done";
        }
        @Override
        protected void process(List<String> chunks) {
            for (String string : chunks){
                if (StatusLevel == 0){
                    StatusMessageBox.append(string);
                }
            }
            super.process(chunks);
        }
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Auto Generated Functions/Variables">
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        structureViewer = new com.cospandesign.gui.structures.StructureViewer();
        lcmGen = new com.cospandesign.gui.lcmgen.LcmGen();
        setupProviderPanel = new javax.swing.JPanel();
        ProviderNameTextField = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        providerTypeList = new javax.swing.JList();
        createProviderButton = new javax.swing.JButton();
        ProviderLayeredPanel = new javax.swing.JLayeredPane();
        tCPGuiProvider = new com.cospandesign.gui.providers.tcp.TCPGuiProvider();
        uDPGuiProvider = new com.cospandesign.gui.providers.udp.UDPGuiProvider();
        jToolBar1 = new javax.swing.JToolBar();
        StructureParserButton = new javax.swing.JButton();
        StructListButton = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        StatusMessageBox = new javax.swing.JTextArea();
        jPanel2 = new javax.swing.JPanel();
        CreateServerButton = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        PortTextBox = new javax.swing.JFormattedTextField();
        AutoCreateServer = new javax.swing.JCheckBox();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        openMenuItem = new javax.swing.JMenuItem();
        saveMenuItem = new javax.swing.JMenuItem();
        saveAsMenuItem = new javax.swing.JMenuItem();
        exitMenuItem = new javax.swing.JMenuItem();
        editMenu = new javax.swing.JMenu();
        cutMenuItem = new javax.swing.JMenuItem();
        copyMenuItem = new javax.swing.JMenuItem();
        pasteMenuItem = new javax.swing.JMenuItem();
        deleteMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        contentMenuItem = new javax.swing.JMenuItem();
        aboutMenuItem = new javax.swing.JMenuItem();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("LCM/DLCM Controller");
        setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getResource("/com/cospandesign/resources/cospandesign.png")));
        setLocationByPlatform(true);
        setResizable(false);

        setupProviderPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Provider Setup"));

        jLabel1.setText("Provider Name");

        jLabel2.setText("Provider Type");

        jScrollPane1.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        providerTypeList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "UDP", "TCP", "File" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        providerTypeList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        providerTypeList.setSelectedIndex(0);
        jScrollPane1.setViewportView(providerTypeList);

        createProviderButton.setText("Create");
        createProviderButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                createProviderButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout setupProviderPanelLayout = new javax.swing.GroupLayout(setupProviderPanel);
        setupProviderPanel.setLayout(setupProviderPanelLayout);
        setupProviderPanelLayout.setHorizontalGroup(
            setupProviderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(setupProviderPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(setupProviderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE)
                    .addComponent(ProviderNameTextField, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2)
                    .addComponent(createProviderButton, javax.swing.GroupLayout.DEFAULT_SIZE, 111, Short.MAX_VALUE))
                .addContainerGap())
        );
        setupProviderPanelLayout.setVerticalGroup(
            setupProviderPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(setupProviderPanelLayout.createSequentialGroup()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ProviderNameTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 94, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 36, Short.MAX_VALUE)
                .addComponent(createProviderButton)
                .addContainerGap())
        );

        ProviderLayeredPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Settings"));
        tCPGuiProvider.setBounds(10, 20, 270, 280);
        ProviderLayeredPanel.add(tCPGuiProvider, javax.swing.JLayeredPane.DEFAULT_LAYER);
        uDPGuiProvider.setBounds(10, 20, 270, 280);
        ProviderLayeredPanel.add(uDPGuiProvider, javax.swing.JLayeredPane.DEFAULT_LAYER);

        jToolBar1.setBorder(javax.swing.BorderFactory.createTitledBorder(""));
        jToolBar1.setRollover(true);

        StructureParserButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/cospandesign/gui/resources/lcmgen.png"))); // NOI18N
        StructureParserButton.setFocusable(false);
        StructureParserButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        StructureParserButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        StructureParserButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                StructureParserButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(StructureParserButton);

        StructListButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/cospandesign/gui/resources/structulist.png"))); // NOI18N
        StructListButton.setFocusable(false);
        StructListButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        StructListButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        StructListButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                StructListButtonActionPerformed(evt);
            }
        });
        jToolBar1.add(StructListButton);

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Status"));

        StatusMessageBox.setColumns(20);
        StatusMessageBox.setRows(5);
        jScrollPane2.setViewportView(StatusMessageBox);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 265, Short.MAX_VALUE)
                .addContainerGap())
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 115, Short.MAX_VALUE)
                .addContainerGap())
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("TCP Server"));

        CreateServerButton.setText("Create");
        CreateServerButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                CreateServerButtonActionPerformed(evt);
            }
        });
        CreateServerButton.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                CreateServerButtonFocusLost(evt);
            }
        });

        jLabel3.setText("Port");

        PortTextBox.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("#"))));
        PortTextBox.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        PortTextBox.setText("7600");

        AutoCreateServer.setSelected(true);
        AutoCreateServer.setText("Create local server automatically");
        AutoCreateServer.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        AutoCreateServer.setHorizontalTextPosition(javax.swing.SwingConstants.LEFT);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(jLabel3)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(PortTextBox, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                        .addComponent(AutoCreateServer)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(CreateServerButton)))
                .addContainerGap())
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(PortTextBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(CreateServerButton)
                    .addComponent(AutoCreateServer))
                .addGap(206, 206, 206))
        );

        fileMenu.setText("File");

        openMenuItem.setText("Open");
        fileMenu.add(openMenuItem);

        saveMenuItem.setText("Save");
        fileMenu.add(saveMenuItem);

        saveAsMenuItem.setText("Save As ...");
        fileMenu.add(saveAsMenuItem);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        editMenu.setText("Edit");

        cutMenuItem.setText("Cut");
        editMenu.add(cutMenuItem);

        copyMenuItem.setText("Copy");
        editMenu.add(copyMenuItem);

        pasteMenuItem.setText("Paste");
        editMenu.add(pasteMenuItem);

        deleteMenuItem.setText("Delete");
        editMenu.add(deleteMenuItem);

        menuBar.add(editMenu);

        helpMenu.setText("Help");

        contentMenuItem.setText("Contents");
        helpMenu.add(contentMenuItem);

        aboutMenuItem.setText("About");
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        setJMenuBar(menuBar);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(setupProviderPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ProviderLayeredPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 287, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
            .addComponent(jToolBar1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 759, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jToolBar1, javax.swing.GroupLayout.PREFERRED_SIZE, 39, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(setupProviderPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(ProviderLayeredPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 269, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(10, 10, 10)
                        .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
            System.exit(0);
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void createProviderButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_createProviderButtonActionPerformed
        createPubSub();
        
    }//GEN-LAST:event_createProviderButtonActionPerformed

    private void CreateServerButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_CreateServerButtonActionPerformed
        try {
            this.StartServer();
        } catch (IOException ex) {
            this.MainError("starting serving: " + ex.getMessage());
        }
    }//GEN-LAST:event_CreateServerButtonActionPerformed

    private void CreateServerButtonFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_CreateServerButtonFocusLost
        this.PortTextBox.setBackground(Color.white);
    }//GEN-LAST:event_CreateServerButtonFocusLost

    private void StructureParserButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StructureParserButtonActionPerformed
        if (lcmGen.isVisible()){
            lcmGen.setVisible(false);
        }
        else{
            lcmGen.setVisible(true);
        }
    }//GEN-LAST:event_StructureParserButtonActionPerformed

    private void StructListButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_StructListButtonActionPerformed
        structureViewer.updateStructureManager();
        if (structureViewer.isVisible()){
            structureViewer.setVisible(false);
        }
        else{
            structureViewer.setVisible(true);
        }
    }//GEN-LAST:event_StructListButtonActionPerformed


    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox AutoCreateServer;
    private javax.swing.JButton CreateServerButton;
    private javax.swing.JFormattedTextField PortTextBox;
    private javax.swing.JLayeredPane ProviderLayeredPanel;
    private javax.swing.JTextField ProviderNameTextField;
    private javax.swing.JTextArea StatusMessageBox;
    private javax.swing.JButton StructListButton;
    private javax.swing.JButton StructureParserButton;
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JMenuItem contentMenuItem;
    private javax.swing.JMenuItem copyMenuItem;
    private javax.swing.JButton createProviderButton;
    private javax.swing.JMenuItem cutMenuItem;
    private javax.swing.JMenuItem deleteMenuItem;
    private javax.swing.JMenu editMenu;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JToolBar jToolBar1;
    private com.cospandesign.gui.lcmgen.LcmGen lcmGen;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JMenuItem pasteMenuItem;
    private javax.swing.JList providerTypeList;
    private javax.swing.JMenuItem saveAsMenuItem;
    private javax.swing.JMenuItem saveMenuItem;
    private javax.swing.JPanel setupProviderPanel;
    private com.cospandesign.gui.structures.StructureViewer structureViewer;
    private com.cospandesign.gui.providers.tcp.TCPGuiProvider tCPGuiProvider;
    private com.cospandesign.gui.providers.udp.UDPGuiProvider uDPGuiProvider;
    // End of variables declaration//GEN-END:variables
// </editor-fold>
}
